package cmgox

// ConditionBuilder 是一个用于构建 MongoDB 查询条件的工具
import (
	"reflect"

	"go.mongodb.org/mongo-driver/bson"
)

type ConditionBuilder struct {
	conditions bson.M
}

func NewConditionBuilder() *ConditionBuilder {
	return &ConditionBuilder{
		conditions: bson.M{},
	}
}

func (cb *ConditionBuilder) AddCondition(field string, operator string, value interface{}) *ConditionBuilder {
	if field == "" || operator == "" {
		panic("Field and operator cannot be empty")
	}
	if cb.conditions[field] == nil {
		cb.conditions[field] = bson.M{}
	}
	if m, ok := value.(bson.M); ok {
		if existing, ok := cb.conditions[field].(bson.M); ok {
			for k, v := range m {
				existing[k] = v
			}
		} else {
			cb.conditions[field] = m
		}
	} else {
		cb.conditions[field] = bson.M{operator: value}
	}
	return cb // 支持链式调用
}

func (cb *ConditionBuilder) addLogicalCondition(logicalOperator string, conditions []bson.M) *ConditionBuilder {
	if len(conditions) == 0 {
		return cb
	}
	if existing, ok := cb.conditions[logicalOperator].([]bson.M); ok {
		cb.conditions[logicalOperator] = append(existing, conditions...)
	} else {
		cb.conditions[logicalOperator] = conditions
	}
	return cb
}

func (cb *ConditionBuilder) AddOrCondition(conditions []bson.M) *ConditionBuilder {
	return cb.addLogicalCondition("$or", conditions)
}

func (cb *ConditionBuilder) AddAndCondition(conditions []bson.M) *ConditionBuilder {
	return cb.addLogicalCondition("$and", conditions)
}

// AddDynamicCondition 动态添加条件
func (cb *ConditionBuilder) AddDynamicCondition(key string, condition bson.M) *ConditionBuilder {
	cb.conditions[key] = condition
	return cb // 支持链式调用
}

// AddOptionalCondition 只在值不为空时添加条件
func (b *ConditionBuilder) AddOptionalCondition(field, operator string, value interface{}) *ConditionBuilder {
	if !isZeroValue(value) {
		return b.AddCondition(field, operator, value)
	}
	return b
}

// AddNestedCondition 添加嵌套条件
func (cb *ConditionBuilder) AddNestedCondition(field string, nestedBuilder *ConditionBuilder) *ConditionBuilder {
	if nestedBuilder != nil {
		cb.conditions[field] = nestedBuilder.Build()
	}
	return cb
}

// isZeroValue 检查值是否为空或零值
func isZeroValue(value interface{}) bool {
	if value == nil {
		return true
	}

	switch v := value.(type) {
	case string:
		return v == ""
	case int:
		return v == 0
	case int64:
		return v == 0
	case float64:
		return v == 0
	case []interface{}:
		return len(v) == 0
	case []string:
		return len(v) == 0
	case map[string]interface{}:
		return len(v) == 0
		// 可以根据需要添加更多类型
	case bool:
		// 假布尔值
		return !v
	}
	// 使用反射处理其他类型
	return reflect.ValueOf(value).IsZero()
}

func (cb *ConditionBuilder) Build() bson.M {
	return cb.conditions
}
